GetUsersElementsQueryHandler.getMonthScopedLeave   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 24
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 24
c 0
b 0
f 0
rs 9.376
cc 3
1
import { QueryHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { IUserRepository } from 'src/Domain/HumanResource/User/Repository/IUserRepository';
4
import { UserElementsView } from '../View/UserElementsView';
5
import { GetUsersElementsQuery } from './GetUsersElementsQuery';
6
import { GetMealTicketsPerMonthQueryHandler } from '../../MealTicket/Query/GetMealTicketsPerMonthQueryHandler';
7
import { GetMealTicketsPerMonthQuery } from '../../MealTicket/Query/GetMealTicketsPerMonthQuery';
8
import { GetLeavesByMonthQueryHandler } from '../../Leave/Query/GetLeavesByMonthQueryHandler';
9
import { GetLeavesByMonthQuery } from '../../Leave/Query/GetLeavesByMonthQuery';
10
import { LeaveRequest } from 'src/Domain/HumanResource/Leave/LeaveRequest.entity';
11
import { IDateUtils } from 'src/Application/IDateUtils';
12
import { MonthDate } from 'src/Application/Common/MonthDate';
13
import { UserLeavesView } from '../View/UserLeavesView';
14
import { LeaveRequestSlotView } from '../../Leave/View/LeaveRequestSlotView';
15
16
@QueryHandler(GetUsersElementsQuery)
17
export class GetUsersElementsQueryHandler {
18
  constructor(
19
    @Inject('IUserRepository')
20
    private readonly userRepository: IUserRepository,
21
    private readonly getLeavesByMonthQueryHandler: GetLeavesByMonthQueryHandler,
22
    private readonly getMealTicketsPerMonth: GetMealTicketsPerMonthQueryHandler,
23
    @Inject('IDateUtils')
24
    private readonly dateUtils: IDateUtils
25
  ) {}
26
27
  public async execute(
28
    query: GetUsersElementsQuery
29
  ): Promise<UserElementsView[]> {
30
    const userViews: UserElementsView[] = [];
31
32
    const date = query.date;
33
34
    const [users, leaves, mealTickets] = await Promise.all([
35
      this.userRepository.findUsersWithPayslipInfo(),
36
      this.getLeavesByMonthQueryHandler.execute(
37
        new GetLeavesByMonthQuery(date)
38
      ),
39
      this.getMealTicketsPerMonth.execute(new GetMealTicketsPerMonthQuery(date))
40
    ]);
41
42
    const mealTicketsByUser: Record<string, number> = {};
43
    mealTickets.forEach(view => {
44
      mealTicketsByUser[view.userId] = view.mealTickets;
45
    });
46
47
    for (const user of users) {
48
      const userLeaves = leaves.getLeavesByUser(user);
49
50
      userViews.push(
51
        new UserElementsView(
52
          user.getFirstName(),
53
          user.getLastName(),
54
          user.getUserAdministrative().getContract(),
55
          user.getUserAdministrative().isExecutivePosition(),
56
          user.getUserAdministrative().getJoiningDate(),
57
          user.getUserAdministrative().getAnnualEarnings() * 0.01,
58
          user.getUserAdministrative().getAnnualEarnings() / 1200,
59
          user.getUserAdministrative().getWorkingTime(),
60
          user.getUserAdministrative().getTransportFee() * 0.01,
61
          user.getUserAdministrative().getSustainableMobilityFee() * 0.01,
62
          mealTicketsByUser[user.getId()],
63
          user.getUserAdministrative().haveHealthInsurance(),
64
          this.createUserLeavesView(userLeaves.paid, date),
65
          this.createUserLeavesView(userLeaves.unpaid, date),
66
          this.createUserLeavesView(userLeaves.medical, date),
67
          this.createUserLeavesView(userLeaves.special, date),
68
          this.createUserLeavesView(userLeaves.postponedWorkedFreeDay, date),
69
          this.createUserLeavesView(userLeaves.relocation, date)
70
        )
71
      );
72
    }
73
74
    return userViews;
75
  }
76
77
  private createUserLeavesView(
78
    leaves: LeaveRequest[],
79
    date: Date
80
  ): UserLeavesView {
81
    const monthDate = this.dateUtils.getMonth(date);
82
83
    let leaveCount = 0;
84
    const leavesSlotViews: LeaveRequestSlotView[] = [];
85
86
    for (const leave of leaves) {
87
      const monthScopedLeave = this.getMonthScopedLeave(leave, monthDate);
88
89
      leaveCount += this.dateUtils.getLeaveDuration(
90
        monthScopedLeave.startDate,
91
        monthScopedLeave.startsAllDay,
92
        monthScopedLeave.endDate,
93
        monthScopedLeave.endsAllDay
94
      );
95
      leavesSlotViews.push(
96
        new LeaveRequestSlotView(
97
          monthScopedLeave.startDate,
98
          monthScopedLeave.startsAllDay,
99
          monthScopedLeave.endDate,
100
          monthScopedLeave.endsAllDay
101
        )
102
      );
103
    }
104
105
    return new UserLeavesView(leaveCount, leavesSlotViews);
106
  }
107
108
  private getMonthScopedLeave(
109
    leave: LeaveRequest,
110
    month: MonthDate
111
  ): LeaveSlot {
112
    const scopedLeave = new LeaveSlot();
113
114
    if (new Date(leave.getStartDate()) >= month.getFirstDay()) {
115
      scopedLeave.startDate = leave.getStartDate();
116
      scopedLeave.startsAllDay = leave.isStartsAllDay();
117
    } else {
118
      scopedLeave.startDate = month.getFirstDay().toISOString();
119
      scopedLeave.startsAllDay = true;
120
    }
121
122
    if (new Date(leave.getEndDate()) <= month.getLastDay()) {
123
      scopedLeave.endDate = leave.getEndDate();
124
      scopedLeave.endsAllDay = leave.isEndsAllDay();
125
    } else {
126
      scopedLeave.endDate = month.getLastDay().toISOString();
127
      scopedLeave.endsAllDay = true;
128
    }
129
130
    return scopedLeave;
131
  }
132
}
133
134
class LeaveSlot {
135
  public startDate: string;
136
  public startsAllDay: boolean;
137
  public endDate: string;
138
  public endsAllDay: boolean;
139
}
140